### KEGG KGML 的下载和解析，重新整合后保存输出

## 本次先提取出反应关系信息，供后续的拓扑学分析使用。

# betweenness centrality 和 出度中心性不应该是 2选1的逻辑， 而应该是 同时做，从不同维度反应结果。

if ( F ) {
    pathway_note  <-  "rno00190"  ## 测试用通路， 可能是没有reaction
    pathway_note  <-  "rno00030"  ## 测试用通路， 普通的一个通路。
    
}

jia_kegg_reaction_catcher <- function (  pathway_name = "rno00030") {  #### 输入一个代谢通路名，如"rno00030" ， 下载并获取该代谢通路的所有内容，并将代谢通路内部的 反应关系提取整理出来做为返回值。
    
    ### 获取通路信息 和 url ， 通过 KEGG API 对 网络数据库进行访问，下载 kgml 文件。 
    pathway_note <-  pathway_name
    url <-  paste0 (  "http://rest.kegg.jp/get/",  pathway_note      , "/kgml" )
    # url
    
    ## 对通路进行解析 ， 提取其中的 反应关系。
    kgml  <-    readLines ( url ) 
    
    ### 2.1 提取开始节点和结束节点
    
    start_lines <-  ( grepl ( "<reaction id=\\\"", kgml ) == T ) %>% which()
    end_lines   <-  ( grepl ( "</reaction>$", kgml ) == T )      %>% which()
    
    reaction_nums <-    start_lines %>% length()
    if ( reaction_nums == 0 ) { 
        cat ( "\nThe pathway " , pathway_name , " doesn't have any reaction between compounds!\n")
        
        return ()
    }
    if ( length(start_lines) != length(end_lines) ){cat ( "Something might goes wrong with your KGML file, cause the starts sign of reaction is different from the ends sign.\n KGML文件解析后，反应开头的标识比反应结束标识多，你快瞅瞅是咋回事儿啊!")}
    
    for ( i in 1:length(start_lines )) {
        if ( i == 1 ) { pooled_reaction_block <-  data.frame() }
        
        temp_reaction_information       <-  kgml [ start_lines[ i ]:end_lines[ i ] ]
        temp_reaction_block <- data.frame (    pathway_note = pathway_note,  temp_reaction_id = i , reaction_information = temp_reaction_information )
        
        pooled_reaction_block <-  rbind ( pooled_reaction_block , temp_reaction_block )
        
    }
    
    pooled_reaction_block %>% head ()
    pooled_reaction_block %>% nrow ()
    
    temp_zz <-  "<reaction id=\"157\" name=\"rn:R02736 rn:R10907\" type= nihaoaiyouwei"     %>% gsub(".*name=\"([rn:R0-9 ]+).*", "\\1", . )
    
    temp_zz %>% gsub("rn:","", . ) %>% gsub ( " ","&", . )
    
    processed_reactions  <-  ddply ( pooled_reaction_block , .( temp_reaction_id ) , function ( each_block ) {
        temp_reaction_name <-  each_block [ 1, "reaction_information"] %>% gsub(".*name=\"([rn:R0-9 ]+).*", "\\1", . )
        reaction_name      <- temp_reaction_name %>% gsub("rn:","", . ) %>% gsub ( " ","&", . )  ### 主要是应对一行中有多个反应的情况。 这样可以将多个反应的结果一同进行处理，结果之间用“&”进行连接。
        IS_reversible <-  each_block [ 1, "reaction_information"] %>% grepl ("type=\\\"reversible\\\"", . )  ### 判断是否是可逆反应，若是可逆反应，那么就反过来再弄一次
        ## 提取底物和产物行内容
        substrate_lines <-  each_block [ , "reaction_information"] %>% grepl ("substrate", . ) %>% which ( ) %>%  each_block [  . , "reaction_information"] 
        product_lines   <-  each_block [ , "reaction_information"] %>% grepl ("product"  , . ) %>% which ( ) %>%  each_block [  . , "reaction_information"] 
        ## 提取底物和产物内部信息
        substrate_id    <-  substrate_lines %>% sub ( ".*cpd:(C[0-9]+)\".*" ,"\\1", . )
        product_id      <-    product_lines %>% sub ( ".*cpd:(C[0-9]+)\".*" ,"\\1", . )
        
        
        ## 将底物和产物提取并且进行组合。
        substrate_temp  <-  rep( substrate_id , rep (length(product_id) ,length( substrate_id ) )   )
        product_temp    <-  rep( product_id ,   length(substrate_id))
        
        substrate_and_product <-  data.frame ( substrate = substrate_temp , product = product_temp , stringsAsFactors = F)
        if ( IS_reversible == T ) {  ## 如果是可逆反应，就将之前的底物和产物交换位置，叠加到原有的数据框中
            mirror_substrate_and_product <-  data.frame ( substrate = product_temp , product = substrate_temp , stringsAsFactors = F)
            substrate_and_product <-  rbind ( substrate_and_product , mirror_substrate_and_product )
        }
        
        substrate_and_product
        
        output_block <-  data.frame (pathway_note = pathway_note, reaction_name  = reaction_name  , IS_reversible = IS_reversible,  substrate_and_product ,stringsAsFactors = F)
        return ( output_block)
    })
    
    processed_reactions  ### 获取某个通路内所有的反应关系结果。
    
    return ( processed_reactions )
}






